`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2021/09/27 10:03:48
// Design Name: 
// Module Name: diffft_8192_b2_v2
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////



module diffft_8192_b2_v2(
input             clk,
input             rstn,

input      [47:0] din,//I[47:24]Q[23:0],fix24_22
input             din_valid,
input             din_last,
output            din_ready,

output reg [79:0] dout,//I[79:40]Q[39:0]:fix40_22
output reg        dout_valid,
output reg        dout_last,
output            error
    );

wire        data_ram_wr;
wire        data_ram_rd;
wire [12:0] data_ram_addr;
wire [79:0] data_ram_dout;
wire        omega_ram_rd;
wire [11:0] omega_ram_addr;
wire [31:0] omega_ram_dout;
wire        bf_din_valid;
wire [79:0] fft_bf2_dout;
wire        fft_dout_reorder;
wire        fft_dout_valid;
wire        fft_dout_last;
wire [12:0] data_ram_reorder_addr;

generate
    genvar i;
	for(i=0;i<13;i=i+1)
	    begin
		    assign data_ram_reorder_addr[12-i]=data_ram_addr[i];
		end
endgenerate

always@(posedge clk)
begin
    if(!rstn) begin
	    
	end
	else if(fft_dout_valid==1) begin
	    dout<=data_ram_dout;
		dout_valid<=fft_dout_valid;
		dout_last<=fft_dout_last;
	end
	else begin
	    dout<=0;
		dout_valid<=0;
		dout_last<=0;
	end
end

diffft_8192_b2_controller_v2
  u_diffft_8192_b2_controller_v2(
  .clk(clk),
  .rstn(rstn),

  .din_valid(din_valid),
  .din_last(din_last),
  .din_ready(din_ready),
  .data_ram_wr_en(data_ram_wr),
  .data_ram_rd_en(data_ram_rd),
  .data_ram_addr(data_ram_addr),
  .omega_ram_rd(omega_ram_rd),
  .omega_ram_addr(omega_ram_addr),
  .bf_din_valid(bf_din_valid),
  .fft_dout_reorder(fft_dout_reorder),
  .fft_dout_valid(fft_dout_valid),
  .fft_dout_last(fft_dout_last),
  .error(error));


reg [79:0] din_d1;
reg [79:0] din_d2;
always@(posedge clk)
begin
    if(!rstn) begin
	    din_d1<=0;
		din_d2<=0;
	end
	else begin
	    if(din_valid) begin
		    din_d1<={{16{din[47]}},din[47:24],{16{din[23]}},din[23:0]};
			din_d2<=din_d1;
		end
		else begin
		    din_d1<=din_d1;
			din_d2<=din_d2;
		end
	end
end

diffft_8192_b2_data_ram
  u_diffft_8192_b2_data_ram(
  .clk(clk),
  .rstn(rstn),

  .wr_en(data_ram_wr),
  .rd_en(data_ram_rd),
  .addr((fft_dout_reorder==0)?data_ram_addr:data_ram_reorder_addr),
  .din((din_ready==1)?din_d2:fft_bf2_dout),
  .dout(data_ram_dout));


diffft_8192_b2_omega_ram
  u_diffft_8192_b2_omega_ram(
  .clk(clk),
  .rstn(rstn),

  .rd_en(omega_ram_rd),
  .addr(omega_ram_addr),
  .dout(omega_ram_dout));

fft_bf2_unit#(
  .WORDDLENGTH(80),//I[79:40]Q[39:0],fix40_22
  .WORDWLENGTH(32))
u_fft_bf2_unit(//I[31:16]Q[15:0],fix16_14
  .clk(clk),
  .rstn(rstn),

  .data_din(data_ram_dout),
  .omega_din(omega_ram_dout),
  .din_valid(bf_din_valid),
  .fft_bf2_dout(fft_bf2_dout));

endmodule
